home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / wb / wb_brushes.lha / Random / random.c < prev    next >
C/C++ Source or Header  |  1992-12-06  |  4KB  |  143 lines

  1. ;/* Random.c - Amiga Mail simple ExAll() example.
  2. lc -cis -v -d0 -j73 -O Random.c
  3. blink from lib:c.o Random.o to Random lib lib:lc.lib lib:amiga.lib ND SC SD
  4. quit
  5.  *
  6.  * Simple program to choose a file randomly from a directory.
  7.  * Usage: Random <pattern>
  8.  *     e.g. copy `random sys:prefs/presets/#?.wbpic` env:sys/wbpicture.prefs
  9.  *
  10.  * Written so that I can choose a random prefs-file for NickPrefs' picture,
  11.  * but could be used in all sorts of situations, I suppose.
  12.  *
  13.  * Note: Random numbers generated by looking at system time in seconds, and
  14.  * taking remainder modulo N (where N is number of files to choose from). This
  15.  * means that running Random many times quickly in succession will NOT generate
  16.  * a random sequence, but method is good enough for system boots etc.
  17.  *
  18.  * Martin W. Scott,  4 December 1992
  19.  */
  20. #include <exec/memory.h>
  21. #include <exec/execbase.h>
  22. #include <dos/dosextens.h>
  23. #include <dos/rdargs.h>
  24. #include <dos/exall.h>
  25.  
  26. #include <clib/exec_protos.h>
  27. #include <clib/dos_protos.h>
  28.  
  29. #include <pragmas/exec_pragmas.h>
  30. #include <pragmas/dos_pragmas.h>
  31.  
  32. #include <string.h>
  33.  
  34. /* Buffersize to receive filenames in */
  35. #define BUFFERSIZE 4096
  36.  
  37. extern struct Library *DOSBase;
  38. VOID _main(VOID);
  39. BOOL ChooseRandom(char *, char *, char *);
  40. extern struct ExecBase *SysBase;
  41.  
  42. VOID
  43. _main(VOID)
  44. {
  45.   struct RDArgs *readargs;
  46.   LONG rargs[2];
  47.   UBYTE *source;
  48.  
  49.   /* Fail silently if < 37 */
  50.   if (SysBase->LibNode.lib_Version >= 37)
  51.   {
  52.     if (readargs = ReadArgs("PATTERN/A", rargs, NULL))
  53.     {
  54.       char fullpath[256], filename[50], pat[50], *t;
  55.  
  56.       source = (UBYTE *) rargs[0];
  57.       strcpy(pat, FilePart(source));
  58.       if (t = PathPart(source))
  59.     *t = '\0';
  60.  
  61.       if (ChooseRandom(source, pat, filename))
  62.       {
  63.     strcpy(fullpath, source);
  64.     AddPart(fullpath, filename, 256);
  65.     PutStr("\"");
  66.     PutStr(fullpath);
  67.     PutStr("\"");
  68.       }
  69.       FreeArgs(readargs);
  70.     }
  71.     else
  72.       PrintFault(IoErr(), NULL);
  73.     CloseLibrary((struct Library *) DOSBase);
  74.   }
  75. }
  76.  
  77. /* seconds since midnight, jan 1, 1978 */
  78. #define SECONDS(ds) (ds.ds_Days * 3600 * 24 + ds.ds_Minute * 60 + ds.ds_Tick / TICKS_PER_SECOND)
  79.  
  80. BOOL
  81. ChooseRandom(char *source, char *pat, char *namebuf)
  82. {
  83.   struct ExAllControl *excontrol;
  84.   struct ExAllData *ead, *buffer;
  85.   char *pattern, *parsebuffer;
  86.   LONG parselen;
  87.   BPTR sourcelock;
  88.   BOOL exmore;
  89.   BOOL success = FALSE;
  90.  
  91.   if (buffer = AllocMem(BUFFERSIZE, MEMF_CLEAR))
  92.   {
  93.     if (sourcelock = Lock(source, SHARED_LOCK))
  94.     {
  95.       if (excontrol = AllocDosObject(DOS_EXALLCONTROL, NULL))
  96.       {
  97.     pattern = (!pat || !*pat) ? "#?" : pat;
  98.     if (parsebuffer = AllocVec(parselen = strlen(pattern) * 3, 0L))
  99.     {
  100.       /* Make pattern uppercase for possible character classes */
  101.       strupr(pattern);
  102.  
  103.       if ((ParsePatternNoCase(pattern, parsebuffer, parselen)) != -1)
  104.       {
  105.         excontrol->eac_MatchString = parsebuffer;
  106.         excontrol->eac_LastKey = 0;
  107.  
  108.         exmore = ExAll(sourcelock, buffer, BUFFERSIZE,
  109.                ED_NAME, excontrol);
  110.  
  111.         if ((exmore == NULL && (IoErr() == ERROR_NO_MORE_ENTRIES)))
  112.         {
  113.           struct DateStamp ds;
  114.           UWORD idx, n;
  115.  
  116.           if ((n = excontrol->eac_Entries) > 0)
  117.           {
  118.         ead = buffer;
  119.         DateStamp(&ds);
  120.         idx = SECONDS(ds) % n;
  121.         while (idx--)
  122.           ead = ead->ed_Next;
  123.         strcpy(namebuf, ead->ed_Name);
  124.         success = TRUE;
  125.           }
  126.         }
  127.       }
  128.       FreeVec(parsebuffer);
  129.     }
  130.     FreeDosObject(DOS_EXALLCONTROL, excontrol);
  131.       }
  132.       else PrintFault(ERROR_NO_FREE_STORE, NULL);
  133.  
  134.       UnLock(sourcelock);
  135.     }
  136.     else PrintFault(IoErr(), source);
  137.  
  138.     FreeMem(buffer, BUFFERSIZE);
  139.   }
  140.   else PrintFault(ERROR_NO_FREE_STORE, NULL);
  141.  
  142.   return success;
  143. }